feat(cli): implement official urBackend CLI (@urbackend/cli) - #340
Conversation
|
Warning Review limit reached
More reviews will be available in 53 minutes and 5 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. 📝 WalkthroughWalkthroughAdds a new ChangesDashboard API: CLI Auth Integration
urBackend CLI SDK
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 16
🧹 Nitpick comments (1)
sdks/urbackend-cli/src/services/analytics.service.ts (1)
9-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winImport the shared analytics types instead of redefining them here.
sdks/urbackend-cli/src/types/analytics.tsalready owns these shapes. Keeping a second copy in the service layer makes the SDK drift the next time the analytics payload changes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@sdks/urbackend-cli/src/services/analytics.service.ts` around lines 9 - 39, The analytics shapes are duplicated in the service layer, which can drift from the shared source of truth. Remove the local GlobalStats and RecentActivityLog definitions from analytics.service.ts and import the shared types from sdks/urbackend-cli/src/types/analytics.ts instead, updating any references in the service to use those imported symbols.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/dashboard-api/src/app.js`:
- Line 82: The CSRF exemption in the request-path check is too broad because
`req.path.startsWith('/api/user/cli')` also matches unrelated routes like
`/api/user/cliff`. Update the path guard in `app.js` so the CLI exemption only
applies to the exact `/api/user/cli` route or paths under `/api/user/cli/`,
while keeping the existing billing webhook exemption unchanged. Use the same
request-handling condition around `req.path` to tighten the match without
affecting other endpoints.
In `@apps/dashboard-api/src/controllers/cli.controller.js`:
- Around line 5-6: The CLI me endpoint is reading the principal from
req.developer._id even though authenticateCLI populates the authenticated
identity on req.user, which can trigger an undefined-property failure before the
not-found path. Update the controller logic in cli.controller.js to use req.user
for the lookup, keeping the existing Developer.findById and select("email plan
githubUsername avatarUrl") flow intact, and ensure any fallback/not-found
handling still works against the authenticated CLI user.
In `@apps/dashboard-api/src/routes/projects.js`:
- Around line 65-66: The collection deletion route is still protected by
authMiddleware, so PAT-based CLI deletes will fail even though the project read
routes already use authFlexible. Update the DELETE handler in the projects
router for the collection deletion path to use authFlexible, keeping it
consistent with getAllProject and getSingleProject so PAT-authenticated requests
can reach the delete logic.
In `@sdks/urbackend-cli/src/commands/auth/login.ts`:
- Around line 15-47: The login command currently logs failures and returns
without setting a non-zero exit status, so `login` can succeed even when
authentication, token validation, or token persistence fails. Update the `login`
flow in the `authenticate`, `saveToken`, and `APIError` handling paths to
terminate with a failing exit code on every error case, including invalid PAT
input, 401 responses, network/API failures, and local write errors from
`saveToken()`. Also separate `saveToken()` from the API `try` so config-write
failures are reported as persistence errors rather than generic connectivity
issues.
In `@sdks/urbackend-cli/src/commands/auth/whoami.ts`:
- Around line 10-45: The whoami command currently only logs errors and returns,
so failures in the not-logged-in path and the APIError handling path still exit
successfully. Update the whoami command logic to return a non-zero exit code
whenever it cannot resolve a valid user identity, including the early token
check, 401 APIError handling, and connectivity failures, while keeping the
existing output behavior for the success path. Use the whoami command flow
around getProfile(), APIError, and logger.error to apply the exit status
consistently.
In `@sdks/urbackend-cli/src/commands/doctor/index.ts`:
- Around line 69-88: The doctor command is collapsing all validation errors into
auth/access failures, so update the `getProfile` and `getProject` checks in
`doctor/index.ts` to distinguish 401 responses from network/backend failures. In
the `result.patValid` and `result.projectAccessible` paths, only set false for
unauthorized responses; for timeouts, DNS, and 5xxs, record a separate “unable
to validate” state instead of marking the token or project invalid. Apply the
same handling in the later validation blocks referenced by the `doctor` flow so
the final report can surface connectivity/backend health separately from login
or project-selection issues.
- Around line 28-35: checkApiReachable currently treats any completed fetch to
apiBase/health as reachable, even if the response is 404 or 500. Update the
checkApiReachable helper in doctor/index.ts to inspect the response from fetch
and only return the elapsed time when the health endpoint responds successfully
(for example, a 2xx status and, if needed, ok is true). If the response is not
successful, return null so doctor does not report the API as reachable for bad
base URLs or failing /health endpoints.
In `@sdks/urbackend-cli/src/commands/project/use.ts`:
- Around line 45-49: The project selection validation in use.ts is too
permissive because parseInt in the prompt handling accepts partially numeric
input like “1foo”. Update the selection logic in the prompt flow around
prompt("Enter project number: ") and the index calculation to validate the
entire answer before converting it, so only pure numeric input is accepted. Keep
the existing invalid-selection check in place and ensure the validation happens
in the same use command path before indexing into projects.
In `@sdks/urbackend-cli/src/core/api.ts`:
- Line 34: The URL construction in api.ts can produce a double slash before api
when config.apiBase already ends with "/", so normalize the base and endpoint
before concatenation. Update the logic around the api endpoint builder to trim
trailing slashes from config.apiBase and ensure endpoint has exactly one leading
slash before composing the final url, so requests from the API client use a
consistent route.
- Around line 38-48: The shared apiFetch() path currently calls fetch() with no
deadline, so CLI requests can hang forever on network stalls; add a timeout
mechanism around the fetch invocation in apiFetch() and ensure timeout-triggered
failures are caught and rethrown as APIError, alongside the existing connection
failure handling. Use the apiFetch() function and its fetch(url, { ...options,
headers }) call as the place to implement this so every CLI command inherits the
bounded request behavior.
In `@sdks/urbackend-cli/src/core/config.ts`:
- Around line 37-40: The token persistence in saveToken currently updates only
pat and leaves currentProject intact, so switching accounts can reuse a stale
project selection. Update saveToken to detect a PAT change and clear
currentProject when the saved token differs from the existing one, using
loadConfig and saveConfig so loginCommand() starts from a clean project state
for the new account.
- Around line 27-34: The config persistence flow in config.ts does not
explicitly restrict permissions, so CONFIG_DIR, the temp file, and CONFIG_PATH
may inherit unsafe modes from the user umask. Update the logic around the
existing atomic write sequence to create the directory with 0700 and write the
PAT file with 0600, then re-apply the file mode after fs.renameSync in the same
save path. Use the existing CONFIG_DIR and CONFIG_PATH constants and the config
write block to keep the fix localized.
In `@sdks/urbackend-cli/src/services/analytics.service.ts`:
- Around line 48-54: The getRecentActivity function is swallowing invalid
analytics responses by returning an empty array, which hides server-side
contract breaks. Update getRecentActivity to validate the apiFetch result and
surface an error when res.data is not a RecentActivityLog[] instead of
converting it to []; use the existing getRecentActivity symbol to locate the
fallback and replace it with explicit failure handling or a thrown error that
preserves the bad payload context.
In `@sdks/urbackend-cli/src/services/collection.service.ts`:
- Around line 31-37: The deleteCollection path is interpolating collectionName
directly into the request URL, so reserved characters can break deletes. Update
deleteCollection in collection.service.ts to URL-encode collectionName before
building the /projects/.../collections/... path, using the same apiFetch call
but with an encoded identifier so names containing /, ?, #, and similar
characters work correctly.
In `@sdks/urbackend-cli/src/utils/prompt.ts`:
- Around line 8-12: The generic prompt helper currently echoes user input, which
is unsafe for secret values. Add a non-echoing secret-input variant in prompt.ts
(for example alongside prompt) that disables terminal echo while reading, and
update the login flow in login.ts to use that secret-specific helper when
capturing the PAT. Keep the existing prompt() for normal input and use unique
identifiers like prompt and the login command’s token capture path to locate the
change.
In `@sdks/urbackend-cli/src/utils/token.ts`:
- Around line 5-6: The PAT validation in isValidPAT is too restrictive because
it hardcodes a narrow charset that can reject server-issued tokens before
authenticateCLI ever hashes them. Update the regex in token.ts so isValidPAT
only enforces the ubpat_ prefix and the minimum remainder length required by the
contract, without assuming the remainder is limited to [a-zA-Z0-9_].
---
Nitpick comments:
In `@sdks/urbackend-cli/src/services/analytics.service.ts`:
- Around line 9-39: The analytics shapes are duplicated in the service layer,
which can drift from the shared source of truth. Remove the local GlobalStats
and RecentActivityLog definitions from analytics.service.ts and import the
shared types from sdks/urbackend-cli/src/types/analytics.ts instead, updating
any references in the service to use those imported symbols.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e403586c-b7e4-4073-b3f1-ff4d5a6df59e
⛔ Files ignored due to path filters (8)
package-lock.jsonis excluded by!**/package-lock.jsonsdks/urbackend-cli/dist/index.cjsis excluded by!**/dist/**sdks/urbackend-cli/dist/index.cjs.mapis excluded by!**/dist/**,!**/*.mapsdks/urbackend-cli/dist/index.d.ctsis excluded by!**/dist/**sdks/urbackend-cli/dist/index.d.tsis excluded by!**/dist/**sdks/urbackend-cli/dist/index.jsis excluded by!**/dist/**sdks/urbackend-cli/dist/index.js.mapis excluded by!**/dist/**,!**/*.mapsdks/urbackend-cli/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (41)
apps/dashboard-api/src/app.jsapps/dashboard-api/src/controllers/cli.controller.jsapps/dashboard-api/src/controllers/pat.controller.jsapps/dashboard-api/src/middlewares/authFlexible.jsapps/dashboard-api/src/middlewares/authMiddleware.jsapps/dashboard-api/src/middlewares/authenticateCLI.jsapps/dashboard-api/src/routes/analytics.jsapps/dashboard-api/src/routes/cli.routes.tsapps/dashboard-api/src/routes/projects.jsapps/dashboard-api/src/routes/user.jssdks/urbackend-cli/bin/ub.jssdks/urbackend-cli/package.jsonsdks/urbackend-cli/src/commands/auth/login.tssdks/urbackend-cli/src/commands/auth/logout.tssdks/urbackend-cli/src/commands/auth/whoami.tssdks/urbackend-cli/src/commands/collection/delete.tssdks/urbackend-cli/src/commands/collection/list.tssdks/urbackend-cli/src/commands/doctor/index.tssdks/urbackend-cli/src/commands/project/info.tssdks/urbackend-cli/src/commands/project/list.tssdks/urbackend-cli/src/commands/project/use.tssdks/urbackend-cli/src/commands/status/index.tssdks/urbackend-cli/src/core/api.tssdks/urbackend-cli/src/core/config.tssdks/urbackend-cli/src/core/constants.tssdks/urbackend-cli/src/core/errors.tssdks/urbackend-cli/src/core/logger.tssdks/urbackend-cli/src/index.tssdks/urbackend-cli/src/services/analytics.service.tssdks/urbackend-cli/src/services/auth.service.tssdks/urbackend-cli/src/services/collection.service.tssdks/urbackend-cli/src/services/project.service.tssdks/urbackend-cli/src/types/analytics.tssdks/urbackend-cli/src/types/auth.tssdks/urbackend-cli/src/types/config.tssdks/urbackend-cli/src/types/project.tssdks/urbackend-cli/src/utils/format.tssdks/urbackend-cli/src/utils/prompt.tssdks/urbackend-cli/src/utils/token.tssdks/urbackend-cli/tsconfig.jsonsdks/urbackend-cli/tsup.config.ts
|
coderabbit comments are still there |
|
fixing |
|
i am slow bcz i dont have any agentic token left @yash-pouranik |
|
codex? |
|
i only use antigravity and copilot @yash-pouranik |
|
@yash-pouranik i am just fixing proposed fix given rabbit |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ci.yml:
- Around line 47-48: The CI job is opting into the Redis-backed path via
REDIS_URL without provisioning Redis, so update the workflow to start a Redis
service for this job (or remove the Redis env if it should not use Redis). Make
the change in the ci workflow near the existing env block so the tests can
connect to localhost:6379 during the run.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a0597de7-7002-4057-bbec-0394ace4dc41
📒 Files selected for processing (13)
.github/workflows/ci.ymlapps/dashboard-api/src/__tests__/routes.user.test.jsapps/dashboard-api/src/app.jsapps/dashboard-api/src/controllers/cli.controller.jsapps/dashboard-api/src/routes/projects.jssdks/urbackend-cli/src/commands/auth/login.tssdks/urbackend-cli/src/commands/auth/whoami.tssdks/urbackend-cli/src/commands/doctor/index.tssdks/urbackend-cli/src/commands/project/use.tssdks/urbackend-cli/src/core/api.tssdks/urbackend-cli/src/core/config.tssdks/urbackend-cli/src/services/analytics.service.tssdks/urbackend-cli/src/utils/token.ts
🚧 Files skipped from review as they are similar to previous changes (9)
- apps/dashboard-api/src/controllers/cli.controller.js
- sdks/urbackend-cli/src/utils/token.ts
- apps/dashboard-api/src/app.js
- apps/dashboard-api/src/routes/projects.js
- sdks/urbackend-cli/src/commands/auth/login.ts
- sdks/urbackend-cli/src/commands/auth/whoami.ts
- sdks/urbackend-cli/src/commands/doctor/index.ts
- sdks/urbackend-cli/src/core/api.ts
- sdks/urbackend-cli/src/commands/project/use.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ci.yml:
- Line 30: The CI workflow YAML has a bad indentation at the services block,
which breaks parsing. Fix the extra leading space before the services key in the
workflow so the mapping aligns correctly with the surrounding jobs/steps
structure. Use the workflow’s services section location to locate the malformed
indentation and ensure the YAML parses cleanly under actionlint and YAMLlint.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d6016a90-bb88-4920-87b8-974da80814dc
⛔ Files ignored due to path filters (4)
sdks/urbackend-cli/dist/index.cjsis excluded by!**/dist/**sdks/urbackend-cli/dist/index.cjs.mapis excluded by!**/dist/**,!**/*.mapsdks/urbackend-cli/dist/index.jsis excluded by!**/dist/**sdks/urbackend-cli/dist/index.js.mapis excluded by!**/dist/**,!**/*.map
📒 Files selected for processing (6)
.github/workflows/ci.ymlapps/dashboard-api/src/middlewares/authMiddleware.jssdks/urbackend-cli/src/commands/auth/login.tssdks/urbackend-cli/src/commands/doctor/index.tssdks/urbackend-cli/src/services/collection.service.tssdks/urbackend-cli/src/utils/prompt.ts
✅ Files skipped from review due to trivial changes (1)
- apps/dashboard-api/src/middlewares/authMiddleware.js
🚧 Files skipped from review as they are similar to previous changes (3)
- sdks/urbackend-cli/src/services/collection.service.ts
- sdks/urbackend-cli/src/commands/auth/login.ts
- sdks/urbackend-cli/src/commands/doctor/index.ts
Summary
Implements the official
ubCLI for urBackend — a Node.js/TypeScript command-line tool that lets developers and AI agents manage urBackend projects without opening the dashboard.Closes #[issue number]
What's new
New package —
sdks/urbackend-cliA fully working CLI published as
@urbackend/cliwith the binaryub. Built with TypeScript, Commander.js, and tsup. Zero runtime dependencies beyondcommander.Commands implemented
ub loginub logoutub whoamiub project listub project use [name|id]ub project info [id]ub collection listub collection delete <name>ub statusub doctorub doctor --jsonPackage structure
Backend changes
New file —
apps/dashboard-api/src/middlewares/authFlexible.jsA middleware that accepts either a session cookie (browser dashboard) or a Bearer PAT token (CLI). Lets the same routes serve both the web UI and the CLI without duplicating route handlers.
Modified —
apps/dashboard-api/src/middlewares/authenticateCLI.jsAdded
_idtoreq.userfor compatibility withauthorizeProject()middleware which readsreq.user._id:Modified —
apps/dashboard-api/src/app.jsAdded CLI route exclusion from CSRF protection. CLI authenticates via Bearer PAT, not cookies, so CSRF does not apply:
Modified —
apps/dashboard-api/src/routes/projects.jsGET /andGET /:projectIdnow useauthFlexibleinstead ofauthMiddlewareso the CLI can list and inspect projects.Modified —
apps/dashboard-api/src/routes/analytics.jsGET /statsandGET /activitynow useauthFlexiblesoub statuscan fetch account usage.Fixed —
apps/dashboard-api/src/controllers/pat.controller.jsFixed a missing closing brace in
revokePATthat caused aSyntaxErroron startup after the PAT UI was merged.Authentication design
patscollection~/.ub/config.json(hidden dot-folder, same convention as GitHub CLI and npm)ubpat_<env>_<base62>, validated client-side before any network callTesting
Tested end-to-end against local
dashboard-api:Known gaps / follow-up PRs
ub pull/ub push/ub generate— requiresPOST /projects/:id/sync-schemabackend endpoint (Phase 3 in CLI roadmap)ub logs— requiresGET /projects/:id/logsstreaming endpoint (Phase 4)ub temp-key— requires ephemeral key model and routes (Phase 5)keytar) is the production improvementInstallation (once published)
Summary by CodeRabbit
ubCLI with commands for login/logout, whoami, project and collection management, and status checks (includingdoctor)./cli/me) to retrieve your developer details and token info.